use std::path::PathBuf;
use std::sync::Arc;
use anyhow::{Result, Context};
use tokio::sync::Mutex;
use log::{info, warn};
use sysinfo::{Process, SystemExt};
use shellexpand;

use super::config::ZedConfig;

/// Zed编辑器服务
pub struct ZedService {
    config: ZedConfig,
    is_running: Arc<Mutex<bool>>,
    instance: Arc<Mutex<Option<ZedInstance>>>,
}

/// Zed编辑器实例
pub struct ZedInstance {
    // 这里会存储Zed编辑器的运行实例信息
    // 比如进程ID、窗口句柄等
    pub process_id: Option<u32>,
    pub workspace_path: Option<PathBuf>,
}

impl ZedService {
    pub fn new(config: ZedConfig) -> Result<Self> {
        Ok(ZedService {
            config,
            is_running: Arc::new(Mutex::new(false)),
            instance: Arc::new(Mutex::new(None)),
        })
    }

    /// 打开指定路径的文件或目录
    pub async fn open_path(&self, path: PathBuf) -> Result<()> {
        let is_running = *self.is_running.lock().await;
        let mut instance = self.instance.lock().await;
        
        if !is_running || instance.is_none() {
            // 如果Zed没有运行，先启动Zed
            self.start_editor().await?;
        }
        
        // 实现打开指定路径的逻辑
        // 检查路径是否存在
        if !path.exists() {
            return Err(anyhow::anyhow!("Path does not exist: {:?}", path));
        }
        
        // 通过命令行参数打开路径
        let zed_exe = self.find_zed_executable()?;
        let _ = std::process::Command::new(zed_exe)
            .arg(path.to_str().context("Invalid path")?)
            .spawn()
            .context("Failed to open path in Zed")?;
        
        Ok(())
    }

    /// 启动Zed编辑器
    pub async fn start_editor(&self) -> Result<()> {
        // 查找Zed可执行文件
        let zed_exe = self.find_zed_executable()?;
        
        // 启动Zed编辑器
        let mut command = std::process::Command::new(zed_exe);
        
        // 添加配置的参数
        if let Some(args) = &self.config.args {
            command.args(args);
        }
        
        let child = command
            .spawn()
            .context("Failed to start Zed")?;
        
        // 记录实例信息
        let mut instance = self.instance.lock().await;
        *instance = Some(ZedInstance {
            process_id: Some(child.id()),
            workspace_path: None,
        });
        
        // 更新运行状态
        *self.is_running.lock().await = true;
        
        Ok(())
    }

    /// 停止Zed编辑器
    pub async fn stop_editor(&self) -> Result<()> {
        // 获取当前实例
        let mut instance = self.instance.lock().await;
        
        if let Some(ref mut zed_instance) = *instance {
            // 尝试终止进程
            if let Some(pid) = zed_instance.process_id {
                if let Ok(process) = sysinfo::Process::new(pid as usize) {
                    process.kill();
                }
            }
            
            // 清除实例信息
            *instance = None;
        }
        
        // 更新运行状态
        *self.is_running.lock().await = false;
        
        Ok(())
    }
    
    /// 查找Zed可执行文件
    fn find_zed_executable(&self) -> Result<String> {
        // 在Windows上查找Zed可执行文件
        // 检查PATH环境变量
        if let Ok(path_env) = std::env::var("PATH") {
            for path in path_env.split(';') {
                let zed_path = PathBuf::from(path).join("zed.exe");
                if zed_path.exists() {
                    return Ok(zed_path.to_string_lossy().to_string());
                }
            }
        }
        
        // 检查常见的安装路径
        let common_paths = [
            "C:\\Program Files\\Zed\\zed.exe",
            "C:\\Program Files (x86)\\Zed\\zed.exe",
            "C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Zed\\zed.exe",
        ];
        
        for path in &common_paths {
            let expanded_path = shellexpand::tilde(path).to_string();
            if PathBuf::from(&expanded_path).exists() {
                return Ok(expanded_path);
            }
        }
        
        // 如果找不到，使用配置中的路径
        if let Some(zed_path) = &self.config.zed_path {
            if PathBuf::from(zed_path).exists() {
                return Ok(zed_path.clone());
            }
        }
        
        Err(anyhow::anyhow!("Zed executable not found"))
    }
}



impl ZedService {
    /// 获取服务名称
    pub fn name(&self) -> &str {
        "zed"
    }

    /// 启动Zed编辑器服务
    pub fn start(&mut self) -> Result<(), String> {
        info!("Starting Zed editor service");
        
        // 检查是否已经运行
        let mut is_running = self.is_running.lock().map_err(|e| format!("Failed to lock running state: {}", e))?;
        if *is_running {
            warn!("Zed editor service already running");
            return Ok(());
        }
        
        // 使用Tokio运行时运行异步方法
        let runtime = tokio::runtime::Builder::new_current_thread()
            .enable_all()
            .build()
            .map_err(|e| format!("Failed to create Tokio runtime: {}", e))?;
        
        runtime.block_on(async {
            if let Err(e) = self.start_editor().await {
                return Err(format!("Failed to start Zed editor: {}", e));
            }
            Ok(())
        })?;
        
        *is_running = true;
        info!("Zed editor service started successfully");
        Ok(())
    }

    /// 停止Zed编辑器服务
    pub fn stop(&mut self) -> Result<(), String> {
        info!("Stopping Zed editor service");
        
        // 检查是否在运行
        let mut is_running = self.is_running.lock().map_err(|e| format!("Failed to lock running state: {}", e))?;
        if !*is_running {
            warn!("Zed editor service not running");
            return Ok(());
        }
        
        // 使用Tokio运行时运行异步方法
        let runtime = tokio::runtime::Builder::new_current_thread()
            .enable_all()
            .build()
            .map_err(|e| format!("Failed to create Tokio runtime: {}", e))?;
        
        runtime.block_on(async {
            if let Err(e) = self.stop_editor().await {
                return Err(format!("Failed to stop Zed editor: {}", e));
            }
            Ok(())
        })?;
        
        *is_running = false;
        info!("Zed editor service stopped successfully");
        Ok(())
    }

    /// 检查服务是否在运行
    pub fn is_running(&self) -> Result<bool, String> {
        let running = self.is_running.lock().map_err(|e| format!("Failed to lock running state: {}", e))?;
        Ok(*running)
    }
}